package com.eastjet.equipment.util;

import cn.hutool.core.io.FileUtil;
import com.ruoyi.common.core.annotation.Excel;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

public class ExcelExportUtil {
    /**
     * 将数据列表导出到Excel文件
     * @param dataList 要导出的数据列表。
     * @param filePath Excel文件保存的路径。
     * @param fileName Excel文件的名称（不含扩展名）。
     * @param <T>      列表中数据的类型。
     */
    public static <T> void exportToExcel(List<T> dataList, String filePath, String fileName) {
        if (dataList == null || dataList.isEmpty()) {
            throw new RuntimeException("数据列表为空，无法导出Excel");
        }

        Workbook workbook = new XSSFWorkbook();
        Sheet sheet = workbook.createSheet("Sheet1");

        // 创建表头
        Row headerRow = sheet.createRow(0);
        Field[] fields = dataList.get(0).getClass().getDeclaredFields();
        for (int i = 0; i < fields.length; i++) {
            Cell cell = headerRow.createCell(i);
            Excel excelAnnotation = fields[i].getAnnotation(Excel.class);
            String headerName = excelAnnotation != null ? excelAnnotation.name() : fields[i].getName();
            cell.setCellValue(headerName);
        }

        // 填充数据
        int rowIndex = 1;
        for (T data : dataList) {
            Row row = sheet.createRow(rowIndex++);
            for (int i = 0; i < fields.length; i++) {
                Field field = fields[i];
                field.setAccessible(true);
                Cell cell = row.createCell(i);
                try {
                    Object value = field.get(data);
                    cell.setCellValue(value != null ? value.toString() : "");
                } catch (IllegalAccessException e) {
                    throw new RuntimeException("无法访问字段值", e);
                }
            }
        }

        // 输出到文件
        File outputFile = new File(filePath + File.separator + fileName + ".xlsx");
        try (FileOutputStream outputStream = new FileOutputStream(outputFile)) {
            workbook.write(outputStream);
        } catch (IOException e) {
            throw new RuntimeException("导出Excel文件失败", e);
        } finally {
            try {
                workbook.close();
            } catch (IOException e) {
                // Ignore
            }
        }
    }

    /**
     * 从Excel文件导入数据到List集合。
     *
     * @param filePath Excel文件路径。
     * @param clazz    映射Excel列的Java对象类。
     * @param <T>      List集合中对象的类型。
     * @return 包含Excel数据的List集合。
     */
    public static <T> List<T> importFromExcel(String filePath, Class<T> clazz) {
        List<T> list = new ArrayList<>();
        try (FileInputStream inputStream = new FileInputStream(new File(filePath));
             Workbook workbook = new XSSFWorkbook(inputStream)) {

            Sheet sheet = workbook.getSheetAt(0);
            Row headerRow = sheet.getRow(0);
            Field[] fields = clazz.getDeclaredFields();

            for (int rowIndex = 1; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
                Row row = sheet.getRow(rowIndex);
                if (row == null) {
                    continue;
                }
                T instance = clazz.getDeclaredConstructor().newInstance();

                for (int cellIndex = 0; cellIndex < fields.length; cellIndex++) {
                    if (cellIndex >= row.getLastCellNum()) {
                        break;
                    }
                    Cell cell = row.getCell(cellIndex);
                    Field field = fields[cellIndex];
                    field.setAccessible(true);
                    Object cellValue = getCellValue(cell);
                    field.set(instance, cellValue);
                }
                list.add(instance);
            }
        } catch (IOException | ReflectiveOperationException e) {
            throw new RuntimeException("导入Excel数据失败", e);
        }
        return list;
    }

    /**
     * 根据单元格类型获取单元格值。
     *
     * @param cell 单元格对象。
     * @return 单元格的值。
     */
    private static Object getCellValue(Cell cell) {
        switch (cell.getCellType()) {
            case STRING:
                return cell.getStringCellValue();
            case NUMERIC:
                if (DateUtil.isCellDateFormatted(cell)) {
                    return cell.getDateCellValue();
                } else {
                    return cell.getNumericCellValue();
                }
            case BOOLEAN:
                return cell.getBooleanCellValue();
            case FORMULA:
                return cell.getCellFormula();
            default:
                return null;
        }
    }
}
